import React, { PureComponent, Fragment } from 'react';
import { connect } from 'dva';
import moment from 'moment';

import {
  Form,
  Card,
  Button,
  Modal,
  Input,
  Divider,
  Popconfirm,
  Row,
  Col,
  Radio,
} from 'antd';

import PageHeaderLayout from '../../layouts/PageHeaderLayout';

import styles from './Route.less';
import StandardTable from '../../components/StandardTable';

const Confirm = Modal.confirm;
const FormItem = Form.Item;

const getValue = obj =>
  Object.keys(obj)
    .map(key => obj[key])
    .join(',');

const CustomModal = Form.create({
  onValuesChange(props, changedFields) {
    const { onModalChange } = props;
    onModalChange(changedFields);
  },
  mapPropsToFields(props) {
    const { modalData } = props;
    if (modalData) {
      return {
        serviceId: Form.createFormField({
          value: modalData.serviceId,
        }),
        path: Form.createFormField({
          value: modalData.path,
        }),
        url: Form.createFormField({
          value: modalData.url,
        }),
        stripPrefix: Form.createFormField({
          value: modalData.stripPrefix,
        }),
        retryable: Form.createFormField({
          value: modalData.retryable,
        }),
        enabled: Form.createFormField({
          value: modalData.enabled,
        }),
        sensitiveheadersList: Form.createFormField({
          value: modalData.sensitiveheadersList,
        }),
      }
    }
  },
})(props => {
  const {
    modalTitle,
    modalWidth,
    modalVisible,
    form,
    handleCloseModal,
    handleOk,
    modalLoading,
  } = props;
  return (
    <Modal
      title={modalTitle}
      width={modalWidth}
      visible={modalVisible}
      onCancel={handleCloseModal}
      onOk={() => {
        form.validateFields((err) => {
          if (err) return;
          handleOk();
        });
      }}
    >
      <Card
        loading={modalLoading}
      >
        <Form layout="vertical">
          <Row gutter={{xs: 12, sm: 24}}>
            <Col xm={24} sm={12}>
              <FormItem label="服务名称">
                {form.getFieldDecorator('serviceId', {
                  rules: [{min: 2, max: 40, required: true, message: '长度在 2 到 40 个字符'}],
                })(<Input placeholder="请输入服务名称" />)}
              </FormItem>
            </Col>
          </Row>
          <Row gutter={24}>
            <Col span={24}>
              <FormItem label="匹配路径">
                {form.getFieldDecorator('path', {
                  rules: [{max: 40, message: '长度在40个字符以内'}],
                })(<Input placeholder="请输入匹配路径" />)}
              </FormItem>
            </Col>
          </Row>
          <Row gutter={24}>
            <Col span={24}>
              <FormItem label="转发地址">
                {form.getFieldDecorator('url', {
                  rules: [{max: 40, message: '长度在40个字符以内'}],
                })(<Input placeholder="请输入转发地址" />)}
              </FormItem>
            </Col>
          </Row>
          <Row gutter={{xs: 12, sm: 24}}>
            <Col xs={24} sm={12}>
              <FormItem label="去掉前缀">
                {form.getFieldDecorator('stripPrefix', {
                  rules: [{required: true, message: '请选择'}],
                })(
                  <Radio.Group>
                    <Radio value="1">是</Radio>
                    <Radio value="0">否</Radio>
                  </Radio.Group>
                )}
              </FormItem>
            </Col>
            <Col xs={24} sm={12}>
              <FormItem label="是否重试">
                {form.getFieldDecorator('retryable', {
                  rules: [{required: true, message: '请选择'}],
                })(
                  <Radio.Group>
                    <Radio value="1">是</Radio>
                    <Radio value="0">否</Radio>
                  </Radio.Group>
                )}
              </FormItem>
            </Col>
          </Row>
          <Row gutter={{xs: 12, sm: 24}}>
            <Col xm={24} sm={12}>
              <FormItem label="是否启用">
                {form.getFieldDecorator('enabled', {
                  rules: [{required: true, message: '请选择'}],
                })(
                  <Radio.Group>
                    <Radio value="1">是</Radio>
                    <Radio value="0">否</Radio>
                  </Radio.Group>
                )}
              </FormItem>
            </Col>
            <Col xm={24} sm={12}>
              <FormItem label="敏感头">
                {form.getFieldDecorator('sensitiveheadersList', {
                  rules: [{max: 40, message: '长度在40 个字符以内'}],
                })(<Input placeholder="请输入敏感头" />)}
              </FormItem>
            </Col>
          </Row>
        </Form>
      </Card>
    </Modal>
  )
});

@connect(({ route, loading }) => ({
  route,
  loading: loading.effects['route/fetch'],
  modalLoading: loading.effects['route/operation'],
}))
@Form.create()
export default class Route extends PureComponent {
  state = {
    selectedRows:[],
    formValues: {},
  };

  componentDidMount() {
    window.addEventListener('resize', this.resize);
    const { dispatch } = this.props;
    dispatch({
      type: 'route/fetch',
      payload: {},
    });
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.resize);
  }

  resize = () => {
    const { dispatch, route: { selectedRoute } } = this.props;
    dispatch({
      type: 'route/changeModalStatus',
      payload: {
        modal: {
          width: window.innerWidth / 2,
        },
        selectedRoute,
      },
    });
  };

  handleOperateRoute = (mode, id = '#') => {
    const { dispatch } = this.props;
    dispatch({
      type: 'route/operation',
      payload: {
        id,
        mode,
      },
    });
  };

  handleCloseModal = () => {
    const { dispatch } = this.props;
    dispatch({
      type: 'route/initModal',
    });
  };

  handleModalChange = changedFields => {
    const { dispatch } = this.props;
    dispatch({
      type: 'route/changeSelectedRoute',
      payload: changedFields,
    });
  };

  handleStandardTableChange = (pagination, filtersArg, sorter) => {
    const { dispatch } = this.props;
    const {formValues} = this.state;

    const filters = Object.keys(filtersArg).reduce((obj, key) => {
      const newObj = {...obj};
      newObj[key] = getValue(filtersArg[key]);
      return newObj;
    }, {});

    const params = {
      page: pagination.current,
      limit: pagination.pageSize,
      ...formValues,
      ...filters,
    };

    if (sorter.field) {
      params.orderByField = `${sorter.field}`;
      params.isAsc = sorter.order === 'ascend';
    }

    dispatch({
      type: 'route/fetch',
      payload: params,
    });
  };

  handleSearch = e => {
    e.preventDefault();

    const { dispatch, form } = this.props;

    form.validateFields((err, fieldsValue) => {
      if (err) return;
      const values = {
        ...fieldsValue,
      };

      this.setState({
        formValues: values,
      });

      dispatch({
        type: 'route/fetch',
        payload: values,
      });
    });
  };

  handleFormReset = () => {
    const {form, dispatch} = this.props;
    form.resetFields();
    this.setState({
      formValues: {},
    });
    dispatch({
      type: 'route/fetch',
      payload: {},
    });
  };

  routeCrud = () => {
    const {
      dispatch,
      route: {
        selectedRoute,
        modal: {
          mode,
        },
      },
    } = this.props;
    switch (mode) {
      case "Add":
        dispatch({
          type: 'route/add',
          payload: {
            serviceId: selectedRoute.serviceId === undefined ? '' : selectedRoute.serviceId,
            path: selectedRoute.path === undefined ? '' : selectedRoute.path,
            url: selectedRoute.url === undefined ? '' : selectedRoute.url,
            stripPrefix: selectedRoute.stripPrefix === undefined ? '0' : selectedRoute.stripPrefix,
            retryable: selectedRoute.retryable === undefined ? '0' : selectedRoute.retryable,
            enabled: selectedRoute.enabled === undefined ? '0' : selectedRoute.enabled,
            sensitiveheadersList: selectedRoute.sensitiveheadersList === undefined ? '' : selectedRoute.sensitiveheadersList,
          },
        });
        break;
      case "Update":
        // do update route
        dispatch({
          type: 'route/upd',
          payload: {
            id: selectedRoute.id,
            serviceId: selectedRoute.serviceId === undefined ? '' : selectedRoute.serviceId,
            path: selectedRoute.path === undefined ? '' : selectedRoute.path,
            url: selectedRoute.url === undefined ? '' : selectedRoute.url,
            stripPrefix: selectedRoute.stripPrefix === undefined ? '0' : selectedRoute.stripPrefix,
            retryable: selectedRoute.retryable === undefined ? '0' : selectedRoute.retryable,
            enabled: selectedRoute.enabled === undefined ? '0' : selectedRoute.enabled,
            sensitiveheadersList: selectedRoute.sensitiveheadersList === undefined ? '' : selectedRoute.sensitiveheadersList,
          },
        });
        break;
      case "Delete":
        // do delete route
        break;
      default:
        break;
    }
  };

  showConfirm = () => {
    const t = this;
    Confirm({
      title: '提示',
      content: '是否确认同步至网关路由?',
      onOk() {
        t.handleOperateRoute("Apply");
      },
      onCancel() {},
    });
  };

  render() {
    const {
      selectedRows,
    } = this.state;
    const {
      form,
      route: { routes, selectedRoute, modal: {width, visible, title} },
      loading,
      modalLoading,
    } = this.props;

    const columns = [
      {
        title: '#',
        dataIndex: 'id',
      },
      {
        title: '服务名称',
        dataIndex: 'serviceId',
      },
      {
        title: '匹配路径',
        dataIndex: 'path',
      },
      {
        title: '转发地址',
        dataIndex: 'url',
      },
      {
        title: '去掉前缀',
        dataIndex: 'stripPrefix',
        render: stripPrefix => stripPrefix === '1' ? '是' : '否',
      },
      {
        title: '是否重试',
        dataIndex: 'retryable',
        render: retryable => retryable === '1' ? '是' : '否',
      },
      {
        title: '是否启用',
        dataIndex: 'enabled',
        render: enabled => enabled === '1' ? '是' : '否',
      },
      {
        title: '敏感头',
        dataIndex: 'sensitiveheadersList',
      },
      {
        title: '创建时间',
        dataIndex: 'createTime',
        render: createTime => moment(createTime).format('YYYY-MM-DD HH:mm'),
      },
      {
        title: '操作',
        render: (_, route) => (
          <Fragment>
            <a onClick={() => this.handleOperateRoute("Update", route.id)}>编辑</a>
            <Divider type="vertical" />
            <Popconfirm title="确定删除?" onConfirm={() => this.handleOperateRoute('Delete', route.id)} okText="删除" cancelText="取消">
              <a>删除</a>
            </Popconfirm>
          </Fragment>
        ),
      },
    ];

    return (
      <PageHeaderLayout title="路由管理">
        <Card bordered={false}>
          <div className={styles.tableList}>
            <div className={styles.tableListForm}>
              <Form onSubmit={this.handleSearch} layout="inline">
                <Row gutter={{md: 8, lg: 24, xl: 48}}>
                  <Col md={8} sm={24} className={styles.colStyle}>
                    <FormItem label="服务名称">
                      {form.getFieldDecorator('service_id')(<Input placeholder="请输入" />)}
                    </FormItem>
                  </Col>
                  <Col md={8} sm={24} className={styles.colStyle}>
                    <span className={styles.submitButtons}>
                      <Button type="primary" htmlType="submit">
                        查询
                      </Button>
                      <Button style={{ marginLeft: 8 }} onClick={this.handleFormReset}>
                        重置
                      </Button>
                    </span>
                  </Col>
                  <Col md={8} sm={24} className={styles.colStyle}>
                    <Button icon="plus" type="primary" onClick={() => this.handleOperateRoute("Add")}>
                      新建
                    </Button>
                    <Button icon="sync" type="primary" onClick={() => this.showConfirm()} style={{ marginLeft: 8 }} >
                      同步
                    </Button>
                  </Col>
                </Row>
              </Form>
            </div>
            <StandardTable
              selectedRows={selectedRows}
              loading={loading}
              rowKey="id"
              data={routes}
              columns={columns}
              onChange={this.handleStandardTableChange}
            />
          </div>
        </Card>
        <CustomModal
          modalTitle={title}
          modalWidth={width}
          modalVisible={visible}
          handleCloseModal={this.handleCloseModal}
          handleOk={this.routeCrud}
          modalLoading={modalLoading}
          modalData={selectedRoute}
          onModalChange={this.handleModalChange}
        />
      </PageHeaderLayout>
    );
  }
}
